Data processors are typically asynchronously interrupted by peripheral devices during the execution of sequences of program steps. Interrupt requests are commonly handled by one of two ways or variations thereof. A first method commonly implemented by processors is a vectored interrupt with program counter substitution. In this method, an interrupt request is not serviced immediately but is made pending until the occurrence of an instruction execution boundary. Therefore, the current instruction is assured of completing execution before servicing the interrupt. At the instruction boundary, the contents of a program counter contains a return address which points to the next instruction that would normally be executed if no interrupt occurred. The return address and varying amounts of other information are then automatically saved in a stack memory. Other information which may be saved includes condition code registers, data registers and address registers. A starting address of the interrupt service routine is then substituted for the previous program counter to effect a change of flow to the interrupt service routine. The substitute value for the program counter may be generated in various ways. A common approach is for the processor to generate an interrupt acknowledge signal. In response to the interrupt acknowledge signal, the interrupting peripheral provides an interrupt vector number which directs the processor to look up a starting address of the interrupt service routine in a memory table. The starting address of the interrupt service routine is loaded into the program counter and the first instruction of the interrupt routine is fetched, decoded and executed by the processor. Execution of a return from interrupt (RTI) instruction completes the interrupt service routine. The RTI instruction effects restoration of the previous status of the processor and reloads the program counter with the return address before normal program execution is resumed.
The previously described method of interrupt execution is slow because of the existence of additional overhead cycles required to process the interrupt. An uncertain amount of delay in servicing an interrupt is always encountered waiting for the current instruction to complete execution. Determination of an initial interrupt address is also inefficient because of the time required to retrieve interrupt vector information. Further, after a starting address has been loaded into a program counter, time is required to fetch and decode the first instruction of the interrupt service routine before execution can begin. Processor efficiency is reduced because the processor is forced to remain idle during change of flow operations caused by the program counter substitution. Finally, delay is encountered when executing the RTI instruction due to time required to restore the processor's previous status conditions and effect the change of flow to the normal instruction stream.
Others have minimized overhead associated with this method of interrupt processing by reducing the number of registers saved when interrupts occur. Others have simplified the steps required to obtain the starting address of the interrupt service routine. Instead of using a scheme to calculate the address of the interrupt service routine, others have stored the starting address in a fixed location in program memory or simply forced the processor to immediately jump to a fixed location. Although such techniques minimize interrupt overhead, inefficiency still exists. Instruction fetch, decode and execution mechanisms in modern processors are often pipelined so that instruction prefetch mechanisms can be overlapped with instruction execution to fetch and decode instructions in advance. As a result, the instruction pipeline is normally full when an interrupt request is received. Therefore, instructions in the pipeline have to be discarded upon execution of an interrupt and delay is encountered with an instruction fetch, decode and execution at a different address associated with an interrupt service routine. This change of flow operation causes lost execution cycles in pipelined data processors.
A second common method of executing interrupts is known as instruction jamming. In this method, an interrupt request is not serviced immediately but is made pending until an instruction execution boundary. Upon completion of the current instruction, the processor provides an interrupt acknowledge signal to a peripheral device. In response, the peripheral device which is requesting the interrupt provides a single instruction such as a jump to subroutine instruction which is jammed into an instruction register. The execution of the jump to subroutine instruction loads the program counter with the starting address of the interrupt service routine. Upon completion of the interrupt service routine, an RTI instruction would load the return address back into the program counter. If the jammed instruction is not a jump to subroutine instruction, the jammed instruction will execute as a single instruction service routine with an implied return from interrupt (RTI). During instruction jamming, the old contents of the program counter are temporarily held constant. This allows the normal program to continue execution without a return address.
In the instruction jamming technique, the processor waits until the current instruction completes execution before the interrupt acknowledge signal fetches the jammed interrupt service routine instruction. The processor also waits until the end of execution of the jammed interrupt service routine instruction before fetching the next instruction of the normal program. Both of these change of flow operations result in wasted overhead cycles. Further, in an instruction jamming interrupt system, the interrupting peripheral device must be designed for the specific processor in order to provide a valid jammed interrupt instruction with correct electrical timing. This limits the compatibility of some commerically available processors with various peripherals.